package com.gree.flowable.app.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.flowable.app.mapper.ActDeModelMapper;
import com.gree.flowable.app.mapper.FlwExNodesetMapper;
import com.gree.flowable.app.mapper.plus.FlwExNodesetService;
import com.gree.flowable.app.pojo.ex.FlowElementEx;
import com.gree.flowable.app.pojo.ex.FlwExNodeset;
import com.gree.flowable.app.pojo.model.PagerModel;
import com.gree.flowable.app.pojo.model.Query;
import com.gree.flowable.app.pojo.model.QueryDeployMO;
import com.gree.flowable.app.pojo.vo.*;
import com.gree.flowable.app.services.BaseProcessService;
import com.gree.flowable.app.services.IFlowableBpmnModelService;
import com.gree.flowable.app.tools.constants.ExcutionType;
import com.gree.flowable.app.tools.constants.NextNodeType;
import com.gree.flowable.app.tools.constants.ReturnCode;
import com.gree.flowable.app.tools.pattern.NextVoContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class IFlowableBpmnModelServiceImpl extends BaseProcessService implements IFlowableBpmnModelService {

    @Autowired
    private ActDeModelMapper actDeModelMapper;

    @Autowired
    private FlwExNodesetMapper flwExNodeSetMapper;

    @Autowired
    private FlwExNodesetService flwExNodesetService;
    @Override
    public BpmnModel getBpmnModelByProcessDefId(String processDefId) {
        return repositoryService.getBpmnModel(processDefId);
    }

    @Override
    public List<FlowNode> findFlowNodes(String processDefId) {
        List<FlowNode> flowNodes = new ArrayList<>();
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        Process process = bpmnModel.getMainProcess();
        Collection<FlowElement> list = process.getFlowElements();
        list.forEach(flowElement -> {
            if (flowElement instanceof FlowNode) {
                flowNodes.add((FlowNode) flowElement);
            }
        });
        return flowNodes;
    }

    @Override
    public List<EndEvent> findEndFlowElement(String processDefId) {
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        if (bpmnModel != null) {
            Process process = bpmnModel.getMainProcess();
            // 查询结束事件的节点元素
            return process.findFlowElementsOfType(EndEvent.class);
        } else {
            return null;
        }
    }
    @Override
    public FlowNode findMainProcessActivityByActivityId(String processDefId, String activityId) {
        FlowNode activity = null;
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        Process process = bpmnModel.getMainProcess();
        FlowElement flowElement = process.getFlowElement(activityId);
        if (flowElement != null) {
            activity = (FlowNode) flowElement;
        }
        return activity;
    }

    @Override
    public FlowNode findFlowNodeByActivityId(String processDefId, String activityId) {
        FlowNode activity = null;
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        List<Process> processes = bpmnModel.getProcesses();
        for (Process process : processes){
            FlowElement flowElement = process.getFlowElementMap().get(activityId);
            if (flowElement != null) {
                activity = (FlowNode) flowElement;
                break;
            }
        }
        return activity;
    }
    @Override
    public boolean checkActivitySubprocessByActivityId(String processDefId, String activityId) {
        boolean flag = true;
        List<FlowNode> activities = this.findFlowNodesByActivityId(processDefId,activityId);
        if (CollectionUtils.isNotEmpty(activities)){
            flag = false;
        }
        return flag;
    }

    public List<FlowNode> findFlowNodesByActivityId(String processDefId, String activityId) {
        List<FlowNode> activities = new ArrayList<>();
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        List<Process> processes = bpmnModel.getProcesses();
        for (Process process : processes) {
            FlowElement flowElement = process.getFlowElement(activityId);
            if (flowElement != null) {
                FlowNode flowNode = (FlowNode) flowElement;
                activities.add(flowNode);
            }
        }
        return activities;
    }

    @Override
    public List<Activity> findActivityByActivityId(String processDefId, String activityId) {
        List<Activity> activities = new ArrayList<>();
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        List<Process> processes = bpmnModel.getProcesses();
        for (Process process : processes) {
            FlowElement flowElement = process.getFlowElement(activityId);
            if (flowElement != null) {
                Activity activity = (Activity) flowElement;
                activities.add(activity);
            }
        }
        return activities;
    }

    @Override
    public Activity findActivityByName(String processDefId, String name) {
        Activity activity = null;
        BpmnModel bpmnModel = this.getBpmnModelByProcessDefId(processDefId);
        Process process = bpmnModel.getMainProcess();
        Collection<FlowElement> list = process.getFlowElements();
        for (FlowElement f : list) {
            if (StringUtils.isNotBlank(name)) {
                if (name.equals(f.getName())) {
                    activity = (Activity) f;
                    break;
                }
            }
        }
        return activity;
    }

    /**
     * 这可能是整个流程引擎模块最复杂的一段代码！
     * 因为要兼顾所有的业务逻辑！
     * 有跳转、并行、是否使用排他网关，要对flowable的API、流程模型有一定了解
     * 为了代码尽可能看起来简略，还使用了策略模式
     * 总之这段代码开发者自己看起来都感觉很绕......
     * 如想再次优化，慎重！如有疑问，联系邮箱aftertoday1@qq.com
     */
    @Override
    public ReturnVO<NextChooseVO> findNextNodesByTaskId(String taskId) {
        ReturnVO returnVO = null;

        if(taskService.getVariable(taskId,"jumpNodeKey") != null){
            // 直接跳转
            String jumpNodeKey = taskService.getVariable(taskId, "jumpNodeKey").toString();
            String jumpNodeName = taskService.getVariable(taskId, "jumpNodeName").toString();
            NextElementVO elementVo = new NextElementVO(jumpNodeName, jumpNodeKey);
            elementVo.setFlowName("跳转至"+ jumpNodeName);
            elementVo.setExcutionType(ExcutionType.SINGLE);
            List<NextElementVO> passlist = new ArrayList<>();
            passlist.add(elementVo);
            NextChooseVO nextChooseVo = new NextChooseVO(NextNodeType.JUMP, passlist,new ArrayList<>());
            return new ReturnVO(ReturnCode.SUCCESS,"查询成功", nextChooseVo);
        }


        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        FlowNode activityNode = this.findFlowNodeByActivityId(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        // 输出连线
        List<SequenceFlow> outgoingFlows = activityNode.getOutgoingFlows();
        NextChooseVO nextChooseVo = null;

        if (outgoingFlows.isEmpty()){
            return new ReturnVO(ReturnCode.FAIL, "null:没有查询到下一节点信息！");
        }
        if (outgoingFlows.size() == 1){
            // 只有一条线通过
            SequenceFlow outgoingFlow = outgoingFlows.get(0);
            FlowElement element = outgoingFlow.getTargetFlowElement();
            // 判断流程线目标元素 用户节点、排他网关、并行网关 、结束流程
            if (element instanceof UserTask){
                // 节点类型
                String category = ((UserTask) element).getCategory()==null?"null":((UserTask) element).getCategory();

                String flowName = outgoingFlow.getName()==null?"null":outgoingFlow.getName();
                NextVoContext<FlowElementEx> context = null;
                if ('R'==flowName.charAt(0)){
                    ArrayList<FlowElementEx> rejectList = new ArrayList<>();
                    if (ExcutionType.PARALLEL.equals(category)){
                        rejectList.add(new FlowElementEx(element, flowName, ExcutionType.PARALLEL));
                    }else {
                        rejectList.add(new FlowElementEx(element, flowName));
                    }
                    context = new NextVoContext<>(NextNodeType.CHOOSE);
                    nextChooseVo = context.getResult(null,rejectList);
                }else{
                    context = new NextVoContext<>(NextNodeType.ONE);
                    if (ExcutionType.PARALLEL.equals(category)){
                        nextChooseVo = context.getResult(new FlowElementEx(element, flowName, ExcutionType.PARALLEL), null);
                    }else {
                        nextChooseVo = context.getResult(new FlowElementEx(element, flowName),null);
                    }
                }
            }else if(element instanceof ExclusiveGateway){
                // 排他网关
                ArrayList<FlowElementEx> passList = new ArrayList<>();
                ArrayList<FlowElementEx> rejectList = new ArrayList<>();
                List<SequenceFlow> nextOutgoingFlows = ((ExclusiveGateway) element).getOutgoingFlows();
                boolean already = false;
                for (SequenceFlow flow : nextOutgoingFlows){
                    FlowElement target = flow.getTargetFlowElement();
                    String flowName = flow.getName()==null?"null":flow.getName();
                    String condition = flow.getConditionExpression()==null?"null":flow.getConditionExpression();
                    try {
                        if (!"null".equals(condition)){
                            already = this.isThrough(task.getExecutionId(), condition);
                        }
                    }catch (Exception e){
                        // dosometing
                    }

                    if (already && 'R'!=flowName.charAt(0)){
                        NextVoContext context = null;

                        if(target instanceof ParallelGateway){
                            List<SequenceFlow> outFlows = ((ParallelGateway) target).getOutgoingFlows();
                            context = new NextVoContext<List<SequenceFlow>>(NextNodeType.COUNTERSIGN);
                            nextChooseVo = context.getResult(outFlows,null);

                        }else if(target instanceof EndEvent){
                            context = new NextVoContext<FlowElementEx>(NextNodeType.END);
                            nextChooseVo = context.getResult(new FlowElementEx(target, "") ,null);
                        }else {
                            context = new NextVoContext<FlowElementEx>(NextNodeType.ONE);
                            String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                            if(ExcutionType.PARALLEL.equals(category)){
                                nextChooseVo = context.getResult(new FlowElementEx(target, flowName, ExcutionType.PARALLEL), null);
                            }else {
                                nextChooseVo = context.getResult(new FlowElementEx(target, flowName), null);
                            }
                        }

                        break;
                    }

                    if ('R'==flowName.charAt(0)){
                        // 驳回的用户节点
                        String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                        if(ExcutionType.PARALLEL.equals(category)){
                            rejectList.add(new FlowElementEx(target, flowName, ExcutionType.PARALLEL));
                        }else {
                            rejectList.add(new FlowElementEx(target, flowName));
                        }
                    }else {
                        if(target instanceof ParallelGateway){
                            SequenceFlow sequenceFlow = ((ParallelGateway) target).getOutgoingFlows().get(0);
                            FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
                            passList.add(new FlowElementEx(targetFlowElement, flowName));
                        }else if(target instanceof EndEvent){
                            passList.add(new FlowElementEx(target, flowName));
                        }else {
                            String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                            if(ExcutionType.PARALLEL.equals(category)){
                                passList.add(new FlowElementEx(target, flowName, ExcutionType.PARALLEL));
                            }else {
                                passList.add(new FlowElementEx(target, flowName));
                            }
                        }
                    }
                }
                if (nextChooseVo == null){
                    NextVoContext<List<FlowElementEx>> context = new NextVoContext<>(NextNodeType.CHOOSE);
                    nextChooseVo = context.getResult(passList,rejectList);
                }
            }else if(element instanceof ParallelGateway){
                // 并行网关 会签场景
                // 找到网关输出线
                List<SequenceFlow> outFlows = ((ParallelGateway) element).getOutgoingFlows();
                if (outFlows.size() == 1){
                    // 此会签结束
                    FlowElement targetEl = outFlows.get(0).getTargetFlowElement();
                    NextVoContext<FlowElementEx> context = new NextVoContext<>(NextNodeType.ONE);
                    nextChooseVo = context.getResult(new FlowElementEx(targetEl, "会签结束"),null);
                }else {
                    // 此会签刚开始 选择各节点会签人
                    NextVoContext<List<SequenceFlow>> context = new NextVoContext<>(NextNodeType.COUNTERSIGN);
                    nextChooseVo = context.getResult(outFlows,null);
                }
            }else if(element instanceof EndEvent){
                // 结束了
                NextVoContext<FlowElementEx> context = new NextVoContext<>(NextNodeType.END);
                nextChooseVo = context.getResult(new FlowElementEx(element, "") ,null);
            }

        }else {
            // 恐怖的多节点
            ArrayList<FlowElementEx> passList = new ArrayList<>();
            ArrayList<FlowElementEx> rejectList = new ArrayList<>();

            boolean already = false;

            for(SequenceFlow flow : outgoingFlows){
                FlowElement target = flow.getTargetFlowElement();
                String flowName = flow.getName()==null?"null":flow.getName();
                String condition = flow.getConditionExpression()==null?"null":flow.getConditionExpression();
                try {
                    if (!"null".equals(condition)){
                        already = this.isThrough(task.getExecutionId(), condition);
                    }
                }catch (Exception e){
                    // dosometing
                }
                if (already && 'R'!=flowName.charAt(0)){
                    NextVoContext context = null;

                    if(target instanceof ParallelGateway){
                        List<SequenceFlow> outFlows = ((ParallelGateway) target).getOutgoingFlows();
                        context = new NextVoContext<List<SequenceFlow>>(NextNodeType.COUNTERSIGN);
                        nextChooseVo = context.getResult(outFlows,null);

                    }else if(target instanceof EndEvent){
                        context = new NextVoContext<FlowElementEx>(NextNodeType.END);
                        nextChooseVo = context.getResult(new FlowElementEx(target, "") ,null);
                    }else {
                        context = new NextVoContext<FlowElementEx>(NextNodeType.ONE);
                        String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                        if(ExcutionType.PARALLEL.equals(category)){
                            nextChooseVo = context.getResult(new FlowElementEx(target, flowName, ExcutionType.PARALLEL), null);
                        }else {
                            nextChooseVo = context.getResult(new FlowElementEx(target, flowName), null);
                        }
                    }
                    break;
                }

                if ('R'==flowName.charAt(0)){
                    // 驳回的用户节点
                    String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                    if(ExcutionType.PARALLEL.equals(category)){
                        rejectList.add(new FlowElementEx(target, flowName, ExcutionType.PARALLEL));
                    }else {
                        rejectList.add(new FlowElementEx(target, flowName));
                    }
                }else {
                    if(target instanceof ParallelGateway){
                        // 会签最后也有一个驳回的情况
                        SequenceFlow sequenceFlow = ((ParallelGateway) target).getOutgoingFlows().get(0);
                        FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
                        passList.add(new FlowElementEx(targetFlowElement, flowName));
                    }else if(target instanceof EndEvent){
                        passList.add(new FlowElementEx(target, flowName));
                    }else {
                        String category = ((UserTask) target).getCategory()==null?"null":((UserTask) target).getCategory();
                        if(ExcutionType.PARALLEL.equals(category)){
                            passList.add(new FlowElementEx(target, flowName, ExcutionType.PARALLEL));
                        }else {
                            passList.add(new FlowElementEx(target, flowName));
                        }
                    }
                }
            }
            if (nextChooseVo == null){
                NextVoContext<List<FlowElementEx>> context = new NextVoContext<>(NextNodeType.CHOOSE);
                nextChooseVo = context.getResult(passList,rejectList);
            }
        }

        if (!nextChooseVo.getRejectNodes().isEmpty()){
            nextChooseVo.getRejectNodes().forEach(nodeVo->{

                String nodeKey = nodeVo.getElementId();
                List<HistoricTaskInstance> querylist = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).taskDefinitionKey(nodeKey).orderByHistoricTaskInstanceEndTime().desc().list();
                HistoricTaskInstance instance = querylist.get(0);
                UserVO userVo = new UserVO();
                userVo.setUserCode(instance.getAssignee());
                nodeVo.getUserList().add(userVo);
            });
        }


        String processDefinitionId = task.getProcessDefinitionId();

        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).latestVersion().singleResult();

        String processKey = definition.getKey();
        int version = definition.getVersion();

        List<NextElementVO> rejectNodes = this.addRoleToList(nextChooseVo.getRejectNodes(), processKey, version);
        List<NextElementVO> passNodes = this.addRoleToList(nextChooseVo.getPassNodes(), processKey, version);

        nextChooseVo.setPassNodes(passNodes);
        nextChooseVo.setRejectNodes(rejectNodes);

        returnVO = new ReturnVO(ReturnCode.SUCCESS,"查询成功", nextChooseVo);
        return returnVO;
    }

    @Override
    public ReturnVO<List<FlowElementVO>> getFLowElementByProceDefKey(String processDefinitionKey) {
        ReturnVO returnVO = null;
        try {
            String processDefId = this.findProcDefIdByKey(processDefinitionKey);
            Process process = repositoryService.getBpmnModel(processDefId).getMainProcess();
            Collection<FlowElement> flowElements = process.getFlowElements();
            List<FlowElementVO> elementVos = new ArrayList<>();
            for (Iterator<FlowElement> iter = flowElements.iterator();iter.hasNext();){
                FlowElement element = iter.next();
                if (element instanceof UserTask) {
                    FlowElementVO vo = new FlowElementVO();
                    vo.setElementId(element.getId());
                    vo.setElementName(element.getName());
                    vo.setElementInfo(element.getDocumentation());
                    elementVos.add(vo);
                }else if(element instanceof StartEvent){
                    FlowElementVO vo = new FlowElementVO();
                    vo.setElementId(element.getId());
                    vo.setElementName(element.getName()==null?"开始":element.getName());
                    vo.setElementInfo(element.getDocumentation());
                    elementVos.add(vo);
                }else if(element instanceof EndEvent){
                    FlowElementVO vo = new FlowElementVO();
                    vo.setElementId(element.getId());
                    vo.setElementName(element.getName()==null?"关闭流程":element.getName());
                    vo.setElementInfo(element.getDocumentation());
                    elementVos.add(vo);
                }
            }
            elementVos.sort(new Comparator<FlowElementVO>() {
                @Override
                public int compare(FlowElementVO o1, FlowElementVO o2) {
                    String s1 = o1.getElementId().substring(1);
                    String s2 = o2.getElementId().substring(1);

                    int diff = Integer.valueOf(s1) - Integer.valueOf(s2);

                    if (diff > 0){
                        return 1;
                    }else if(diff <0){
                        return -1;
                    }
                    return 0;
                }
            });

            returnVO = new ReturnVO(ReturnCode.SUCCESS, "OK", elementVos);
        }catch (Exception e){
            e.printStackTrace();
            returnVO = new ReturnVO(ReturnCode.FAIL, e.getMessage());
        }
        return returnVO;
    }

    @Override
    public PagerModel<ModelExVO> queryDeployList(QueryDeployMO params, Query query) {
        Page<TaskVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<ModelExVO> modelExVOIPage = actDeModelMapper.queryDeploy(page, params);
        return new PagerModel<>(modelExVOIPage);
    }

    @Override
    public void insertFlwNode(List<FlwExNodeset> elementVos) {
        List<FlwExNodeset> maxVersionList = flwExNodeSetMapper.getMaxVersionList(elementVos.get(0).getProcessKey());
        if (CollectionUtils.isNotEmpty(maxVersionList)){
            for (Iterator<FlwExNodeset> iterator = maxVersionList.iterator(); iterator.hasNext();){
                FlwExNodeset next = iterator.next();
                elementVos.forEach((item)->{
                    if (item.getElementId().equals(next.getElementId())){
                        item.setRoleId(next.getRoleId());
                        item.setNodeLaster(next.getNodeLaster());
                        return;
                    }
                });
            }
        }
        flwExNodesetService.saveBatch(elementVos);
    }

    @Override
    public List<NextElementVO> addRoleToList(List<NextElementVO> list, String processKey, int version) {
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }

        list.forEach(item->{
            QueryWrapper<FlwExNodeset> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(FlwExNodeset::getProcessKey, processKey).eq(FlwExNodeset::getVers, version).eq(FlwExNodeset::getElementId, item.getElementId());
            FlwExNodeset selectOne = flwExNodeSetMapper.selectOne(wrapper);
            if (selectOne == null){
                return;
            }
            item.setRoleId(selectOne.getRoleId());
        });

        return list;
    }

    @Override
    public NextElementVO addRole(NextElementVO param, String processKey, int version) {
        QueryWrapper<FlwExNodeset> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FlwExNodeset::getProcessKey, processKey).eq(FlwExNodeset::getVers, version).eq(FlwExNodeset::getElementId, param.getElementId());
        FlwExNodeset selectOne = flwExNodeSetMapper.selectOne(wrapper);
        if (selectOne != null){
            param.setRoleId(selectOne.getRoleId());
        }
        return param;
    }

    @Override
    public Map<String, Integer> findNextNodesByTask(Task task) {
        Map<String, Integer> map = new HashMap<>();
        int pass = 0;
        int reject = 0;
        String taskId = task.getId();
        if(taskService.getVariable(taskId,"jumpNodeKey") != null){
            // 直接跳转
            String jumpNodeKey = taskService.getVariable(taskId, "jumpNodeKey").toString();
            String jumpNodeName = taskService.getVariable(taskId, "jumpNodeName").toString();
            NextElementVO elementVo = new NextElementVO(jumpNodeName, jumpNodeKey);
            map.put("pass", 1);
            map.put("reject", 0);
            return map;
        }

        FlowNode activityNode = this.findFlowNodeByActivityId(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        // 输出连线
        List<SequenceFlow> outgoingFlows = activityNode.getOutgoingFlows();
        if (outgoingFlows.isEmpty()){
            // do nothing
        }else if(outgoingFlows.size() == 1) {
            SequenceFlow outgoingFlow = outgoingFlows.get(0);
            FlowElement element = outgoingFlow.getTargetFlowElement();
            if (element instanceof UserTask){
                String flowName = outgoingFlow.getName()==null?"null":outgoingFlow.getName();
                if ('R'==flowName.charAt(0)){
                    reject ++;
                }else{
                    pass ++;
                }
            }else if(element instanceof ExclusiveGateway){
                List<SequenceFlow> nextOutgoingFlows = ((ExclusiveGateway) element).getOutgoingFlows();
                for (SequenceFlow flow : nextOutgoingFlows){
                    String flowName = flow.getName()==null?"null":flow.getName();
                    if ('R'==flowName.charAt(0)){
                        // 驳回的用户节点
                        reject ++;
                    }else {
                        pass ++;
                    }
                }
            }else if(element instanceof ParallelGateway){
                List<SequenceFlow> outFlows = ((ParallelGateway) element).getOutgoingFlows();
                pass = outFlows.size();
            }else if(element instanceof EndEvent){
                // 结束了
                pass ++;
            }
        }else {
            for(SequenceFlow flow : outgoingFlows){
                FlowElement target = flow.getTargetFlowElement();
                String flowName = flow.getName()==null?"null":flow.getName();
                if ('R'==flowName.charAt(0)){
                    reject ++;
                }else{
                    if(target instanceof ParallelGateway){
                        pass = pass + ((ParallelGateway) target).getOutgoingFlows().size();
                    }else{
                        pass++;
                    }
                }
            }
        }

        map.put("pass", pass);
        map.put("reject", reject);

        return map;
    }

    @Override
    public ReturnVO<NextElementVO> findNowNodeByTaskId(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        NextElementVO nextElementVO = new NextElementVO();
        FlowNode activityNode = this.findFlowNodeByActivityId(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        nextElementVO.setName(activityNode.getName());
        nextElementVO.setElementId(activityNode.getId());
        nextElementVO.setDocumentation(activityNode.getDocumentation());
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).latestVersion().singleResult();
        return new ReturnVO(ReturnCode.SUCCESS,"查询成功", this.addRole(nextElementVO, definition.getKey(), definition.getVersion()));
    }

}
